# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2010  Jason Power <power.jg@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from PyQt4 import QtCore
from PyQt4.QtGui import *

import sys
import os
sys.path.append(os.getcwd())

from editorScene import EditorScene
from toolBoxes import ToolWidget, ItemWidget
from libraryDialog import LibraryDialog

from ui_editorWindow import Ui_EditorWindow

import pybel

class EditorWindow(QMainWindow):
	def __init__(self, controller=None, mol=None, callback=None, parent=None):
		QMainWindow.__init__(self, parent)

		self.controller = controller
		self.callback = callback

		self.forceClose = False

		self.ui = Ui_EditorWindow()
		self.ui.setupUi(self)

		self.editMenu = QMenu("Edit", self)
		self.ui.menubar.addMenu(self.editMenu)
		self.ui.menubar.addMenu(self.ui.menuInsert)
		self.ui.menubar.addMenu(self.ui.menuView)

		self.mainScene = EditorScene(mol)
		self.ui.mainView.setScene(self.mainScene)

		self.tools = ToolWidget(self.mainScene, self)
		self.items = ItemWidget(self.mainScene, self)

		self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.tools)
		self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.items)

		self.toolboxMenu = self.createPopupMenu()
		self.toolboxMenu.setTitle("Toolboxes")
		self.toolboxMenu.setParent(self)
		self.ui.menuView.addMenu(self.toolboxMenu)

		self.undoAction = QAction("Undo", self)
		self.undoAction.setShortcut(QKeySequence.Undo)
		self.redoAction = QAction("Redo", self)
		self.redoAction.setShortcut(QKeySequence.Redo)

		self.editMenu.addAction(self.undoAction)
		self.editMenu.addAction(self.redoAction)

		#self.connect(self.undoAction, QtCore.SIGNAL("triggered()"), self.mainScene.undoStack.undo)
		#self.connect(self.redoAction, QtCore.SIGNAL("triggered()"), self.mainScene.undoStack.redo)

		self.connect(self.ui.actionNew_Compound, QtCore.SIGNAL("triggered()"), self.clearScene)
		self.connect(self.ui.actionLoad_File, QtCore.SIGNAL("triggered()"), self.mainScene.loadFile)
		self.connect(self.ui.actionSave_File, QtCore.SIGNAL("triggered()"), self.mainScene.saveFile)
		self.connect(self.ui.actionExport_Image, QtCore.SIGNAL("triggered()"), self.exportImage)

		self.connect(self.ui.actionFrom_Library, QtCore.SIGNAL("triggered()"), self.getLibrary)
		self.connect(self.ui.actionSMILES, QtCore.SIGNAL("triggered()"), self.getSMILES)

		self.connect(self.ui.actionShow_Hydrogens, QtCore.SIGNAL("toggled(bool)"), self.mainScene.setShowHydrogens)
		
		self.connect(self.ui.buttonBox, QtCore.SIGNAL("rejected()"), self.doClose)
		self.connect(self.ui.buttonBox, QtCore.SIGNAL("accepted()"), self.returnCompound)

		if not self.callback:
			self.ui.buttonBox.hide()

	def getSMILES(self):
		smiles, ok = QInputDialog.getText(self, "SMILES Input", "SMILES String", QLineEdit.Normal, "")
		if ok:
			try:
				mol = pybel.readstring("smiles", str(smiles))
				self.mainScene.addMolecule(mol.OBMol)
			except IOError:
				dialog = QMessageBox(QMessageBox.Warning, "Invalid SMILES", "The smiles string you entered (%s) is invalid" % (smiles), QMessageBox.Ok)
				dialog.exec_()

	def getLibrary(self):
		dialog = LibraryDialog(self.mainScene, self)
		mol = dialog.exec_()
		print mol

	def clearScene(self):
		self.mainScene.clear()
		self.ui.actionShow_Hydrogens.setChecked(False)

	def closeEvent(self, event):
		if self.forceClose:
			self.mainScene.clear()
			return
		if self.callback:
			if self.maybeCallback():
				event.accept()
				self.mainScene.clear()
			else:
				event.ignore()
		else:
			if self.maybeSave():
				event.accept()
				self.mainScene.clear()
			else:
				event.ignore()


	def maybeCallback(self):
		box = QMessageBox(self)
		box.addButton(QMessageBox.Yes)
		box.addButton(QMessageBox.Discard)
		box.addButton(QMessageBox.Cancel)
		box.setWindowTitle("Leave compound editor?")
		box.setText("Do you want to export the compound back to OriginDB?")

		ret = box.exec_()

		if ret == QMessageBox.Yes:
			self.callback(pybel.Molecule(self.mainScene.getMol()))
			return True
		elif ret == QMessageBox.Discard:
			return True
		else:
			return False

	def maybeSave(self):
		box = QMessageBox(self)
		box.addButton(QMessageBox.Yes)
		box.addButton(QMessageBox.Discard)
		box.addButton(QMessageBox.Cancel)
		box.setWindowTitle("Exit compound editor?")
		box.setText("Do you want to save the compound you are currently editing?")

		ret = box.exec_()

		if ret == QMessageBox.Yes:
			if self.mainScene.saveFile():
				return True
			else:
				return False
		elif ret == QMessageBox.Discard:
			return True
		else:
			return False

	def returnCompound(self):
		self.callback(pybel.Molecule(self.mainScene.getMol()))
		self.forceClose = True
		self.close()

	def doClose(self):
		self.forceClose = True
		self.close()

	def exportImage(self):
		dialog = QFileDialog(self, "Select file to save structure image")
		dialog.setAcceptMode(QFileDialog.AcceptSave)
		dialog.setFileMode(QFileDialog.AnyFile)
		dialog.setNameFilters(["PNG image file (*.png)"])

		filename = ""
		typ = ""
		if dialog.exec_():
			filename = dialog.selectedFiles()[0]
			if str(filename).lower().endswith('png'):
				typ = "png"

		if filename and typ:
			image = self.mainScene.exportImage()
			image.save(filename)